export const FunctionData = [
    {
        key: 1,
        name: "after",
        remark: "执行n次func后触发函数",
        use: "_.after(n, func)",
        description: `_.before的反向函数;此方法创建一个函数，当他被调用n或更多次之后将马上触发func 。`,
        argument: `
1.n (number): func 方法应该在调用多少次后才执行。
2.func (Function): 用来限定的函数。
        `,
        return: "(Function): 返回新的限定函数。",
        case: `
var saves = ['profile', 'settings'];

var done = _.after(saves.length, function() {
  console.log('done saving!');
});

_.forEach(saves, function(type) {
  asyncSave({ 'type': type, 'complete': done });
});
// => Logs 'done saving!' after the two async saves have completed.
        `,
    },
    {
        key: 2,
        name: "ary",
        remark: "限制传参数量",
        use: "_.ary(func, [n=func.length])",
        description: `创建一个调用func的函数。调用func时最多接受 n个参数，忽略多出的参数。`,
        argument: `
1.func (Function): 需要被限制参数个数的函数。
2.[n=func.length] (number): 限制的参数数量。
        `,
        return: "(Function): 返回新的覆盖函数。",
        case: `
_.map(['6', '8', '10'], _.ary(parseInt, 1));
// => [6, 8, 10]
        `,
    },
    {
        key: 3,
        name: "before",
        remark: "限制函数执行次数，超过次数时返回最后一次执行结果",
        use: "_.before(n, func)",
        description: `创建一个调用func的函数，通过this绑定和创建函数的参数调用func，调用次数不超过 n 次。 之后再调用这个函数，将返回一次最后调用func的结果。`,
        argument: `
1.n (number): 超过多少次不再调用func（注：限制调用func 的次数）。
2.func (Function): 限制执行的函数。
        `,
        return: "(Function): 返回新的限定函数。",
        case: `
jQuery(element).on('click', _.before(5, addContactToList));
// => allows adding up to 4 contacts to the list
        `,
    },
    {
        key: 4,
        name: "bind",
        remark: "绑定this到指定函数上",
        use: "_.bind(func, thisArg, [partials])",
        description: `
        创建一个调用func的函数，thisArg绑定func函数中的 this (注：this的上下文为thisArg) ，并且func函数会接收partials附加参数。
_.bind.placeholder值，默认是以 _ 作为附加部分参数的占位符。
注意: 不同于原生的 Function#bind，这个方法不会设置绑定函数的 "length" 属性。`,
        argument: `
1.func (Function): 绑定的函数。
2.thisArg (*): func 绑定的this对象。
3.[partials] (...*): 附加的部分参数。
        `,
        return: "(Function): 返回新的绑定函数。",
        case: `
var greet = function(greeting, punctuation) {
  return greeting + ' ' + this.user + punctuation;
};

var object = { 'user': 'fred' };

var bound = _.bind(greet, object, 'hi');
bound('!');
// => 'hi fred!'

// Bound with placeholders.
var bound = _.bind(greet, object, _, '!');
bound('hi');
// => 'hi fred!'
        `,
    },
    {
        key: 5,
        name: "bindKey",
        remark: "绑定this到指定函数上【不理解】",
        use: "_.bindKey(object, key, [partials])",
        description: `
创建一个函数,在object[key]上通过接收partials附加参数，调用这个方法。
这个方法与_.bind 的不同之处在于允许重新定义绑定函数即使它还不存在。 浏览Peter Michaux's article 了解更多详情。
_.bind.placeholder值，默认是以 _ 作为附加部分参数的占位符。
        `,
        argument: `
1.object (Object): 需要绑定函数的对象。
2.key (string): 需要绑定函数对象的键。
3.[partials] (...*): 附加的部分参数。
        `,
        return: "(Function): 返回新的绑定函数。",
        case: `
var object = {
  'user': 'fred',
  'greet': function(greeting, punctuation) {
    return greeting + ' ' + this.user + punctuation;
  }
};

var bound = _.bindKey(object, 'greet', 'hi');
bound('!');
// => 'hi fred!'

object.greet = function(greeting, punctuation) {
  return greeting + 'ya ' + this.user + punctuation;
};

bound('!');
// => 'hiya fred!'

// Bound with placeholders.
var bound = _.bindKey(object, 'greet', _, '!');
bound('hi');
// => 'hiya fred!'
        `,
    },
    {
        key: 6,
        name: "curry",
        remark: "函数柯里化（将多入参函数变成单入参函数，最主要的场景就是减少不必要的固定入参）",
        use: "_.curry(func, [arity=func.length])",
        description: `
创建一个函数，该函数接收 func 的参数，要么调用func返回的结果，如果 func 所需参数已经提供，则直接返回 func 所执行的结果。或返回一个函数，接受余下的func 参数的函数，可以使用 func.length 强制需要累积的参数个数。
_.curry.placeholder值，默认是以 _ 作为附加部分参数的占位符。
Note: 这个方法不会设置 curried 函数的 "length" 属性。
        `,
        argument: `
1.func (Function): 用来柯里化（curry）的函数。
2.[arity=func.length] (number): 需要提供给 func 的参数数量。
        `,
        return: "(Function): 返回新的柯里化（curry）函数。",
        case: `
var abc = function(a, b, c) {
  return [a, b, c];
};

var curried = _.curry(abc);

curried(1)(2)(3);
// => [1, 2, 3]

curried(1, 2)(3);
// => [1, 2, 3]

curried(1, 2, 3);
// => [1, 2, 3]

// Curried with placeholders.
curried(1)(_, 3)(2);
// => [1, 2, 3]
        `,
    },
    {
        key: 7,
        name: "curryRight",
        remark: "类似curry，执行顺序从右开始",
        use: "_.curryRight(func, [arity=func.length])",
        description: `
这个方法类似_.curry。 除了它接受参数的方式用_.partialRight 代替了_.partial。
_.curryRight.placeholder值，默认是以 _ 作为附加部分参数的占位符。
Note: 这个方法不会设置 curried 函数的 "length" 属性。
        `,
        argument: `
1.func (Function): 用来柯里化（curry）的函数。
2.[arity=func.length] (number): 需要提供给 func 的参数数量。
        `,
        return: "(Function): 返回新的柯里化（curry）函数。",
        case: `
var abc = function(a, b, c) {
  return [a, b, c];
};

var curried = _.curryRight(abc);

curried(3)(2)(1);
// => [1, 2, 3]

curried(2, 3)(1);
// => [1, 2, 3]

curried(1, 2, 3);
// => [1, 2, 3]

// Curried with placeholders.
curried(3)(1, _)(2);
// => [1, 2, 3]
        `,
    },
    {
        key: 8,
        name: "debounce",
        remark: "防抖",
        use: "_.debounce(func, [wait=0], [options=])",
        description: `
创建一个 debounced（防抖动）函数，该函数会从上一次被调用后，延迟 wait 毫秒后调用 func 方法。 debounced（防抖动）函数提供一个 cancel 方法取消延迟的函数调用以及 flush 方法立即调用。 可以提供一个 options（选项） 对象决定如何调用 func 方法，options.leading 与|或 options.trailing 决定延迟前后如何触发（注：是 先调用后等待 还是 先等待后调用）。 func 调用时会传入最后一次提供给 debounced（防抖动）函数 的参数。 后续调用的 debounced（防抖动）函数返回是最后一次 func 调用的结果。
注意: 如果 leading 和 trailing 选项为 true, 则 func 允许 trailing 方式调用的条件为: 在 wait 期间多次调用防抖方法。
如果 wait 为 0 并且 leading 为 false, func调用将被推迟到下一个点，类似setTimeout为0的超时。
SeeDavid Corbacho's articlefor details over the differences between_.debounce and_.throttle.
        `,
        argument: `
1.func (Function): 要防抖动的函数。
2.[wait=0] (number): 需要延迟的毫秒数。
3.[options=] (Object): 选项对象。
4.[options.leading=false] (boolean): 指定在延迟开始前调用。
5.[options.maxWait] (number): 设置 func 允许被延迟的最大值。
6.[options.trailing=true] (boolean): 指定在延迟结束后调用。
        `,
        return: "(Function): 返回新的 debounced（防抖动）函数。",
        case: `
// 避免窗口在变动时出现昂贵的计算开销。
jQuery(window).on('resize', _.debounce(calculateLayout, 150));
 
// 当点击时 sendMail 随后就被调用。
jQuery(element).on('click', _.debounce(sendMail, 300, {
  'leading': true,
  'trailing': false
}));
 
// 确保 batchLog 调用1次之后，1秒内会被触发。
var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });
var source = new EventSource('/stream');
jQuery(source).on('message', debounced);
 
// 取消一个 trailing 的防抖动调用
jQuery(window).on('popstate', debounced.cancel);
        `,
    },
    {
        key: 9,
        name: "defer",
        remark: "推迟调用func，直到当前堆栈清理完毕",
        use: "_.defer(func, [args])",
        description: `
推迟调用func，直到当前堆栈清理完毕。 调用时，任何附加的参数会传给func。
        `,
        argument: `
1.func (Function): 要延迟的函数。
2.[args] (...*): 会在调用时传给 func 的参数。
        `,
        return: "(number):返回计时器 id。",
        case: `
_.defer(function(text) {
  console.log(text);
}, 'deferred');
// => 一毫秒或更久一些输出 'deferred'。
        `,
    },
    {
        key: 10,
        name: "delay",
        remark: "延迟一段时间调用函数",
        use: "_.delay(func, wait, [args])",
        description: `
延迟 wait 毫秒后调用 func。 调用时，任何附加的参数会传给func。
        `,
        argument: `
1.func (Function): 要延迟的函数。
2.wait (number): 要延迟的毫秒数。
3.[args] (...*): 会在调用时传入到 func 的参数。
        `,
        return: "(number): 返回计时器 id",
        case: `
_.delay(function(text) {
  console.log(text);
}, 1000, 'later');
// => 一秒后输出 'later'。
        `,
    },
    {
        key: 11,
        name: "flip",
        remark: "反转传入参数",
        use: "_.flip(func)",
        description: `
创建一个函数，调用func时候接收翻转的参数。
        `,
        argument: `
func (Function): 要翻转参数的函数。
        `,
        return: "(Function): 返回新的函数。",
        case: `
var flipped = _.flip(function() {
  return _.toArray(arguments);
});

flipped('a', 'b', 'c', 'd');
// => ['d', 'c', 'b', 'a']
        `,
    },
    {
        key: 12,
        name: "memoize",
        remark: "缓存函数执行结果，源对象改变也不会影响",
        use: "_.memoize(func, [resolver])",
        description: `
创建一个会缓存 func 结果的函数。 如果提供了 resolver ，就用 resolver 的返回值作为 key 缓存函数的结果。 默认情况下用第一个参数作为缓存的 key。 func 在调用时 this 会绑定在缓存函数上。
注意: 缓存会暴露在缓存函数的 cache 上。 它是可以定制的，只要替换了 _.memoize.Cache 构造函数，或实现了Map 的 delete, get, has, 和 set方法。
        `,
        argument: `
1.func (Function): 需要缓存化的函数.
2.[resolver] (Function): 这个函数的返回值作为缓存的 key。
        `,
        return: "(Function): 返回缓存化后的函数。",
        case: `
var object = { 'a': 1, 'b': 2 };
var other = { 'c': 3, 'd': 4 };
 
var values = _.memoize(_.values);
values(object);
// => [1, 2]
 
values(other);
// => [3, 4]
 
object.a = 2;
values(object);
// => [1, 2]
 
// 修改结果缓存。
values.cache.set(object, ['a', 'b']);
values(object);
// => ['a', 'b']
 
// 替换 _.memoize.Cache。
_.memoize.Cache = WeakMap;
        `,
    },
    {
        key: 13,
        name: "negate",
        remark: "创建一个针对断言函数 func 结果取反的函数",
        use: "_.negate(predicate)",
        description: `
创建一个针对断言函数 func 结果取反的函数。 func 断言函数被调用的时候，this 绑定到创建的函数，并传入对应参数。
        `,
        argument: `
predicate (Function): 需要对结果取反的函数。
        `,
        return: "(Function): 返回一个新的取反函数。",
        case: `
function isEven(n) {
  return n % 2 == 0;
}

_.filter([1, 2, 3, 4, 5, 6], _.negate(isEven));
// => [1, 3, 5]
        `,
    },
    {
        key: 14,
        name: "once",
        remark: "限制函数只能执行一次",
        use: "_.once(func)",
        description: `
创建一个只能调用 func 一次的函数。 重复调用返回第一次调用的结果。 func 调用时， this 绑定到创建的函数，并传入对应参数。
        `,
        argument: `
func (Function): 指定的触发的函数。
        `,
        return: "(Function): 返回新的受限函数。",
        case: `
var initialize = _.once(createApplication);
initialize();
initialize();
// initialize 只能调用 createApplication 一次。
        `,
    },
    {
        key: 15,
        name: "overArgs",
        remark: "可以用于对不同参数执行不同函数",
        use: "_.overArgs(func, [transforms=[_.identity]])",
        description: `
创建一个函数，调用func时参数为相对应的transforms的返回值。
        `,
        argument: `
func (Function):要包裹的函数。
        `,
        return: "(Function): 返回新函数。",
        case: `
function doubled(n) {
  return n * 2;
}

function square(n) {
  return n * n;
}

var func = _.overArgs(function(x, y) {
  return [x, y];
}, [square, doubled]);

func(9, 3);
// => [81, 6]

func(10, 5);
// => [100, 10]
        `,
    },
    {
        key: 16,
        name: "partial",
        remark: "通过函数预设参数，比如给传入的参数添加前缀或者后缀，用占位符是添加后缀",
        use: "_.partial(func, [partials])",
        description: `
创建一个函数。 该函数调用 func，并传入预设的 partials 参数。 这个方法类似_.bind，除了它不会绑定 this。
这个 _.partial.placeholder 的值，默认是以 _ 作为附加部分参数的占位符。
注意: 这个方法不会设置 "length" 到函数上。
        `,
        argument: `
1.func (Function): 需要预设的函数
2.[partials] (...*): 预设的参数
        `,
        return: "(Function): 返回预设参数的函数。",
        case: `
var greet = function(greeting, name) {
  return greeting + ' ' + name;
};

var sayHelloTo = _.partial(greet, 'hello');
sayHelloTo('fred');
// => 'hello fred'

// 使用了占位符。
var greetFred = _.partial(greet, _, 'fred');
greetFred('hi');
// => 'hi fred'
        `,
    },
    {
        key: 17,
        name: "partialRight",
        remark: "通过函数预设参数，比如给传入的参数添加前缀或者后缀，用占位符是添加前缀",
        use: "_.partialRight(func, [partials])",
        description: `
这个函数类似_.partial，除了预设参数被附加到接受参数的后面。
这个 _.partialRight.placeholder 的值，默认是以 _ 作为附加部分参数的占位符。
注意: 这个方法不会设置 "length" 到函数上。
        `,
        argument: `
1.func (Function): 需要预设的函数。
2.[partials] (...*): 预设的参数。
        `,
        return: "(Function):返回预设参数的函数。",
        case: `
var greet = function(greeting, name) {
  return greeting + ' ' + name;
};

var greetFred = _.partialRight(greet, 'fred');
greetFred('hi');
// => 'hi fred'

// 使用了占位符。
var sayHelloTo = _.partialRight(greet, 'hello', _);
sayHelloTo('fred');
// => 'hello fred'
        `,
    },
    {
        key: 18,
        name: "rearg",
        remark: "修改参数参数位置",
        use: "_.rearg(func, indexes)",
        description: `
创建一个函数,调用func时，根据指定的 indexes 调整对应位置参数。其中第一个索引值是对应第一个参数，第二个索引值是作为第二个参数，依此类推。
        `,
        argument: `
1.func (Function): 待调用的函数。
2.indexes (...(number|number[])): 排列参数的位置。
        `,
        return: "(Function): 返回新的函数。",
        case: `
var rearged = _.rearg(function(a, b, c) {
  return [a, b, c];
}, [2, 0, 1]);

rearged('b', 'c', 'a')
// => ['a', 'b', 'c']
        `,
    },
    {
        key: 19,
        name: "rest",
        remark: "this指针绑定",
        use: "_.rest(func, [start=func.length-1])",
        description: `
创建一个函数，调用func时，this绑定到创建的新函数，并且start之后的参数作为数组传入。
Note: 这个方法基于rest parameter[https://mdn.io/rest_parameters]。
        `,
        argument: `
1.func (Function): 要应用的函数。
2.[start=func.length-1] (number): rest 参数的开始位置。
        `,
        return: "(Function): 返回新的函数。",
        case: `
var say = _.rest(function(what, names) {
  return what + ' ' + _.initial(names).join(', ') +
    (_.size(names) > 1 ? ', & ' : '') + _.last(names);
});

say('hello', 'fred', 'barney', 'pebbles');
// => 'hello fred, barney, & pebbles'
        `,
    },
    {
        key: 20,
        name: "spread",
        remark: "this指针绑定",
        use: "_.spread(func, [start=0])",
        description: `
创建一个函数，调用func时，this绑定到创建的新函数，把参数作为数组传入，类似于Function#apply.
        `,
        argument: `
1.func (Function): 要应用传播参数的函数。
2.[start=0] (number): spread 参数的开始位置.
        `,
        return: "(Function): 返回新的函数。",
        case: `
var say = _.spread(function(who, what) {
  return who + ' says ' + what;
});

say(['fred', 'hello']);
// => 'fred says hello'

var numbers = Promise.all([
  Promise.resolve(40),
  Promise.resolve(36)
]);

numbers.then(_.spread(function(x, y) {
  return x + y;
}));
// => a Promise of 76
        `,
    },
    {
        key: 21,
        name: "throttle",
        remark: "节流",
        use: "_.throttle(func, [wait=0], [options=])",
        description: `
创建一个节流函数，在 wait 秒内最多执行 func 一次的函数。 该函数提供一个 cancel 方法取消延迟的函数调用以及 flush 方法立即调用。 可以提供一个 options 对象决定如何调用 func 方法， options.leading 与|或 options.trailing 决定 wait 前后如何触发。 func 会传入最后一次传入的参数给这个函数。 随后调用的函数返回是最后一次 func 调用的结果。
注意: 如果 leading 和 trailing 都设定为 true 则 func 允许 trailing 方式调用的条件为: 在 wait 期间多次调用。
如果 wait 为 0 并且 leading 为 false, func调用将被推迟到下一个点，类似setTimeout为0的超时。
查看David Corbacho's article【https://css-tricks.com/debouncing-throttling-explained-examples/】
了解_.throttle【https://www.lodashjs.com/docs/lodash.throttle#throttle】 与_.debounce【https://www.lodashjs.com/docs/lodash.throttle#debounce】 的区别。
        `,
        argument: `
1.func (Function): 要节流的函数。
2.[wait=0] (number): 需要节流的毫秒。
3.[options=] (Object): 选项对象。
4.[options.leading=true] (boolean): 指定调用在节流开始前。
5.[options.trailing=true] (boolean): 指定调用在节流结束后。
        `,
        return: "(Function): 返回节流的函数。",
        case: `
// 避免在滚动时过分的更新定位
jQuery(window).on('scroll', _.throttle(updatePosition, 100));
 
// 点击后就调用 renewToken，但5分钟内超过1次。
var throttled = _.throttle(renewToken, 300000, { 'trailing': false });
jQuery(element).on('click', throttled);
 
// 取消一个 trailing 的节流调用。
jQuery(window).on('popstate', throttled.cancel);
        `,
    },
    {
        key: 22,
        name: "unary",
        remark: "限制参数数量为1",
        use: "_.unary(func)",
        description: `
创建一个最多接受一个参数的函数，忽略多余的参数。
        `,
        argument: `
func (Function): 要处理的函数。
        `,
        return: "(Function): 返回新函数。",
        case: `
_.map(['6', '8', '10'], _.unary(parseInt));
// => [6, 8, 10]
        `,
    },
    {
        key: 23,
        name: "wrap",
        remark: "没理解",
        use: "_.wrap(value, [wrapper=identity])",
        description: `
创建一个函数。提供的 value 包装在 wrapper 函数的第一个参数里。 任何附加的参数都提供给 wrapper 函数。 被调用时 this 绑定在创建的函数上。
        `,
        argument: `
1.value (*): 要包装的值。
2.[wrapper=identity] (Function): 包装函数。
        `,
        return: "(Function): 返回新的函数。",
        case: `
var p = _.wrap(_.escape, function(func, text) {
  return '<p>' + func(text) + '</p>';
});

p('fred, barney, & pebbles');
// => '<p>fred, barney, & pebbles</p>'
        `,
    },
    {
        key: 24,
        name: "stubArray",
        remark: "这个方法返回一个新的空数组",
        use: "_.stubArray()",
        description: `
                这个方法返回一个新的空数组。
        `,
        argument: `
没有参数
        `,
        return: "(Array): 返回新的空数组。",
        case: `
var arrays = _.times(2, _.stubArray);

console.log(arrays);
// => [[], []]

console.log(arrays[0] === arrays[1]);
// => false
        `,
    },
];
